
//
// test the byteorder.hpp
//

#include <iostream>
#include <string>

using namespace std;

#include <byteorder.hpp>
#include <xbase_utility.hpp>

template<typename order>
struct IntegerWithByteorder {
	typedef order byteorder;
	typedef long long value_type;
	
	value_type n;

	IntegerWithByteorder(value_type pn) : n(pn) {}

	value_type value() const {
		return n;
	}
};

int main(int argc, char**argv) {

	unsigned long long n = 0x1234567890abcdefULL;

	cout << "ntoh: " << hex << kb::ntoh(n) << endl;
	cout << "hton: " << hex << kb::hton(n) << endl;

	cout << "kb::byteorder_cast<kb::little_endian, kb::little_endian>(n) = "
	     << kb::byteorder_cast<kb::little_endian, kb::little_endian>(n)
	     << endl;
	cout << "kb::byteorder_cast<kb::little_endian, kb::big_endian>(n) = "
	     << kb::byteorder_cast<kb::little_endian, kb::big_endian>(n)
	     << endl;
	cout << "kb::byteorder_cast<kb::big_endian, kb::big_endian>(n) = "
	     << kb::byteorder_cast<kb::big_endian, kb::big_endian>(n)
	     << endl;
	cout << "kb::byteorder_cast<kb::big_endian, kb::little_endian>(n) = "
	     << kb::byteorder_cast<kb::big_endian, kb::little_endian>(n)
	     << endl;

	cout << "kb::byteorder_cast<kb::network_byteorder, kb::host_byteorder>(n) = "
	     << kb::byteorder_cast<kb::network_byteorder, kb::host_byteorder>(n)
	     << endl;
	cout << "kb::byteorder_cast<kb::network_byteorder, kb::network_byteorder>(n) = "
	     << kb::byteorder_cast<kb::network_byteorder, kb::network_byteorder>(n)
	     << endl;
	cout << "kb::byteorder_cast<kb::host_byteorder, kb::network_byteorder>(n) = "
	     << kb::byteorder_cast<kb::host_byteorder, kb::network_byteorder>(n)
	     << endl;
	cout << "kb::byteorder_cast<kb::host_byteorder, kb::host_byteorder>(n) = "
	     << kb::byteorder_cast<kb::host_byteorder, kb::host_byteorder>(n)
	     << endl;

	// cout << "kb::from_order_cast<kb::network_byteorder>(n) = "
	//      <<  kb::from_order_cast<kb::network_byteorder>(n)
	//      << endl;
	// cout << "kb::to_order_cast<kb::network_byteorder>(n) = "
	//      <<  kb::to_order_cast<kb::network_byteorder>(n)
	//      << endl;

	// IntegerWithByteorder<kb::network_byteorder> net_n(n);
	// IntegerWithByteorder<kb::host_byteorder> host_n(n);
	// cout << "kb::byteorder_cast<kb::network_byteorder>(host_n) = "
	//      <<  kb::byteorder_cast<kb::network_byteorder>(host_n).n
	//      << endl;
	// cout << "kb::byteorder_cast<kb::host_byteorder>(net_n) = "
	//      <<  kb::byteorder_cast<kb::host_byteorder>(net_n).n
	//      << endl;
	// cout << "kb::byteorder_cast<kb::network_byteorder>(n) = "
	//      <<  kb::byteorder_cast<kb::network_byteorder>(n)
	//      << endl;
	// cout << "kb::byteorder_cast<kb::host_byteorder>(n) = "
	//      <<  kb::byteorder_cast<kb::host_byteorder>(n)
	//      << endl;

	// ===============

	const char *n_str = reinterpret_cast<const char*>(&n);
	const std::string str = dump_string_hex(n_str, sizeof(n));
	char *end = NULL;
	unsigned long long value = strtoull(str.c_str(), &end, 16);
	assert(end == str.c_str() + sizeof(n) * 2);
	unsigned long long n_recovered = kb::byteorder_cast<kb::host_byteorder, kb::network_byteorder>(value);
	assert(n_recovered == n);

	return 0;
}
